"""
des: 文件管理
author: 邵宁
date: 2022-08-13
"""
import os
import shutil
import logging

from util import path
logging.basicConfig(level=logging.INFO, format='[%(asctime)s] %(message)s', datefmt='%Y/%m/%d %H:%M:%S')


class FileManage:
    def __init__(self):
        self.config = {}
        self.disk_path_list = []
        # self.get_disk_free()

    def mount(self, _path):
        if os.path.isdir(_path):
            abspath = os.path.abspath(_path)
            if abspath not in self.disk_path_list:
                self.disk_path_list.append(abspath)
                logging.info(f"挂载成功，{_path} 可用容量：{self.storage_human_show(shutil.disk_usage(abspath)[2])}")
                return True
            else:
                logging.error(f"目录 {_path} 已挂载！")
                return False
        else:
            logging.error("请检查路径是否正确！")
            return False

    def unmount(self, _path):
        if os.path.isdir(_path):
            abspath = os.path.abspath(_path)
            if abspath in self.disk_path_list:
                self.disk_path_list.remove(abspath)
                logging.info(f"取消挂载 {_path} 成功！")
                return True
            else:
                logging.error("当前目录未挂载！")
                return False
        else:
            logging.error("请检查路径是否正确！")
            return False

    @staticmethod
    def storage_human_show(value, tag="bytes"):
        if tag == "bytes":
            if value < 1024:
                return str(value)
            elif value < 1024 * 1024:
                return str(value // 1024) + ' B'
            elif value < 1024 * 1024 * 1024:
                return str(value // 1024 // 1024) + ' MB'
            elif value < 1024 * 1024 * 1024 * 1024:
                return str(value // 1024 // 1024 // 1024) + ' GB'
            elif value < 1024 * 1024 * 1024 * 1024 * 1024:
                return str(value // 1024 // 1024 // 1024 // 1024) + ' TB'

    def get_disk_free_list(self):
        disk_free_list = []
        for disk_path_one in self.disk_path_list:
            _, _, free = shutil.disk_usage(disk_path_one)
            disk_free_list.append(free)
        return disk_free_list

    def get_disk_free(self):
        disk_free = 0
        for disk_path_one in self.disk_path_list:
            _, _, free = shutil.disk_usage(disk_path_one)
            disk_free += free
        return disk_free

    def get_dir_free(self):
        return self.get_disk_free()

    @staticmethod
    def get_dir_used_one(_path):
        total_size = 0
        for r, d, f in os.walk(_path):
            for f_o in f:
                fp = os.path.join(r, f_o)
                if not os.path.islink(fp):  # 不检测符号链接
                    total_size += os.path.getsize(fp)
        return total_size

    def get_dir_used_all(self):
        disk_used = 0
        for disk_path_one in self.disk_path_list:
            disk_used += self.get_dir_used_one(disk_path_one)
        return disk_used

    def config_load(self, path_config="/etc/ccp_file_manager.conf"):
        if os.path.exists(path_config):
            with open(path_config) as f:
                for line in f.readlines():
                    print(line)
                    self.config["file_mod"] = "755"

    def file_save_disk_path_choice(self, file_size):
        # TODO 选出一个最合适的存储目录
        print(file_size)
        return self.disk_path_list[0]

    def file_save_check(self, args=None):
        """
        功能：检查文件是否可存
        :param args: 其中包含文件的大小
        :return: args：包含是否可存，可存储的目录，
        """
        if args is None:
            args = {}
        print(self.disk_path_list)
        return args

    def file_save(self, file_obj, args=None):
        """
        :param file_obj: 文件的二进制句柄
        :param args: 保存文件的参数，其中包含：指定存储目录（可选）、文件大小、文件名字
        :return:
        """
        if args is None:
            args = {}
        disk_path = args.get("disk_path", "")
        if not os.path.isdir(disk_path):
            logging.error(f"磁盘路径错误：{disk_path}")
            return False
        if disk_path != "" and os.path.abspath(disk_path) not in self.disk_path_list:
            logging.error(f"指定存储目录未挂载：{disk_path}")
            return False
        if disk_path == "":
            disk_path = self.file_save_disk_path_choice(file_size=5666)  # TODO 选择一个大小合适的目录
        dir_path = os.path.abspath(disk_path)
        para_file_mod = self.config.get("file_mod", "755")
        para_file_mod = args.get("file_mod", para_file_mod)
        para_file_name = args.get("file_name", path.get_file_name_random())
        para_file_path = os.path.join(dir_path, para_file_name)

        print(file_obj)


if __name__ == '__main__':
    fm = FileManage()
    fm.mount("./")
    fm.mount("./")
    fm.unmount("./")
